package com.jwt.token.controller;

import com.jwt.token.domain.SysUser;
import com.jwt.token.domain.UserToken;
import com.jwt.token.service.sysUserService;
import com.jwt.token.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/sysUser")
public class UserController {

    @Autowired
    private sysUserService sysUserService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Value("${jwt.key}")
    private String jwtKey;		// 从配置中读取到 jwt 的key

    /**
     * 登录的controller层方法 这里获取到前端发送过来的请求体，取出其中的用户名和密码，和数据库比对如果无误的话，签发token，并返回给前端。
     * （API响应结果还没有封装，看着有点乱，嘿嘿）
     */

    @PostMapping(value = "/login")
    public Map<String, Object> login(HttpServletRequest request, @RequestBody SysUser sysUser) {

        Map<String, Object> map = new HashMap<>();
        String userName = sysUser.getUserName();
        Integer userId = sysUser.getUserId();
        boolean remember = sysUser.isRemember();
        // 查询用户信息
        if (sysUserService.login(userId,userName)) {

            UserToken userToken = new UserToken();
            /**
             * 登录信息
             * 客户端ip（如果是反向代理，要根据情况获取实际的ip）
             *  UserAgent
             */
//            String ip = request.getRemoteAddr();
            String ip = getIpAddr(request);
            String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
            // 登录时间
            LocalDateTime issuedAt = LocalDateTime.now();
            // 过期时间，如果是“记住我”，则Token有效期是7天，反之则是半个小时
            LocalDateTime expiresAt = issuedAt.plusSeconds(remember
                    ? TimeUnit.DAYS.toSeconds(7)
                    : TimeUnit.MINUTES.toSeconds(30));
            // 距离过期时间剩余的秒数
            int expiresSeconds = (int) Duration.between(issuedAt, expiresAt).getSeconds();

            // 随机生成uuid，作为token的id
            userToken.setId(UUID.randomUUID().toString().replace("-", ""));
            userToken.setUserId(sysUser.getUserId());
            userToken.setIssuedAt(issuedAt);
            userToken.setExpiresAt(expiresAt);
            userToken.setRemember(remember);
            userToken.setUserAgent(userAgent);
            userToken.setIp(ip);
            // 生成token
            String token = TokenUtil.sign(String.valueOf(userId),userName,jwtKey);
            if (null != token) {
                redisTemplate.opsForValue().set("token:"+sysUser.getUserId(), token, expiresSeconds, TimeUnit.SECONDS);
                map.put("code", "200");
                map.put("message", "认证成功");
                map.put("token", token);
                return map;
            }
        }
        map.put("code", "00000");
        map.put("message", "认证失败");
        return map;
    }

    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if(ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip ==null || ip.length() ==0 ||"unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    @PostMapping(value = "/edit")
    public Map<String, Object> edit(@RequestBody SysUser sysUser) {

        Map<String, Object> map = new HashMap<>();
        String userName = sysUser.getUserName();
        Integer userId = sysUser.getUserId();
        if (sysUserService.login(userId,userName)) {
//            String token = TokenUtil.sign(userId,userName,jwtKey);
//            if (null != token) {
//                String userToken = redisTemplate.opsForValue().get("token"+userId);
//                map.put("code", "200");
//                map.put("message", "认证成功");
//                map.put("userToken", userToken);
//                return map;
//            }
        }
        return map;
    }
}
